<template>
  <div id="content-box">
    <div id="tab-module">
      <el-tabs type="card" v-model="tabsActive" id="tabs-box" @tab-remove="tabRemove" @tab-click="setActiveTab" @contextmenu.prevent.native="openContextMenu($event)">
        <el-tab-pane label="首页" name="HOME" />
        <el-tab-pane v-for="(item) in tabsList" :key="item.name" :label="item.label" :name="item.name" closable />
      </el-tabs>
      <ul v-show="contextMenuVisible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
        <li @click="closeAllTabs">关闭所有</li>
        <li v-show="tabsList.length>1" @click="closeOtherTabs('other')">关闭其他</li>
      </ul>
    </div>
    <div id="main-content">
      <div class="components-loading" v-show="false">
        <i class="fa fa-spinner fa-spin"></i>
      </div>
      <!--怎么找对应的页面：通过router/tabComponent.js文件的路由路径找-->
      <el-scrollbar style="height:100%;" ref="main-content">
        <!-- <keep-alive :include="keepAliveList">
        </keep-alive> -->
        <component :is="tabsActive"></component>
      </el-scrollbar>
    </div>
    <div class="back-top-box" v-show="visiable" @click="handleScrollTop">
      <div class="mask"></div>
      <div class="content">
        <i class="el-icon-top"></i>
        <p>返回顶部</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'tabs',
  data () {
    return {
      tabsActive: 'HOME', // 当前的标签页
      tabsList: [], // 标签页列表
      keepAliveList: ['HOME'], // 缓存队列，关闭标签时销毁该组件，不在队列内的组件不缓存
      params: {}, // 页签所接收的参数
      contextMenuVisible: false,
      left: '',
      top: '',
      scrollTop: null,
      visiable: false
    }
  },
  computed: {
    tabsParams () {
      return this.params
    }
  },

  methods: {
    // 右击事件
    openContextMenu (e) {
      if (e.srcElement.id && (e.srcElement.id === `tab-${this.tabsActive}`) && this.tabsList.length > 0) {
        this.contextMenuVisible = true
        this.left = e.clientX - 190
        this.top = e.clientY - 46
      } else {
        this.contextMenuVisible = false
      }
    },
    // 关闭所有
    closeAllTabs () {
      this.tabsList = []
      this.keepAliveList = ['HOME']
      this.$nextTick(() => {
        this.tabsActive = 'HOME'
        this.setActiveTab()
      })
      this.contextMenuVisible = false
    },
    // 关闭其他
    closeOtherTabs (par) {
      this.keepAliveList = ['HOME', this.tabsActive]
      this.tabsList.forEach((item) => {
        if (item.name === this.tabsActive) {
          this.tabsList = [item]
          this.$nextTick(() => {
            this.setActiveTab()
          })
        }
      })
    },
    // 关闭contextMenu
    closeContextMenu () {
      this.contextMenuVisible = false
    },
    tabRemove (targetName) {
      // 先删除缓存队列的对应标签，然后再跳转组件
      this.deleteKeepList(targetName).then(mess => {
        // 如果点击关闭的标签页等于当前标签页，直接关闭当前页，组件跳转到上一个标签，如果上一个为空，则直接跳转到HOME
        this.tabsList.forEach((item, index) => {
          if (targetName === item.name) {
            this.tabsList.splice(index, 1)
            this.$nextTick(() => {
              this.tabsActive = index !== 0 ? this.tabsList[index - 1].name : 'HOME'
              this.setActiveTab()
              this.contextMenuVisible = false
            })
          }
        })
      }).catch(Error => {
        console.log(Error)
      })
    },

    // 改变缓存队列，返回一个promise对象，操作缓存后再做组件跳转
    addKeepList (url) {
      return new Promise((resolve, reject) => {
        if (!url) {
          reject(new Error('参数不存在'))
        }
        // 判断是否存在缓存队列内，存在，直接跳转到对应组件，不存在，push到队列内，然后再做组件跳转
        let isPush = this.keepAliveList.includes(url)
        console.log(this.keepAliveList, '页签是否存在队列中')
        if (!isPush) {
          this.keepAliveList.push(url)
          resolve('add')
        } else {
          resolve('isDone')
        }
      })
    },

    // 删除缓存队列指定标签
    deleteKeepList (targetName) {
      return new Promise((resolve, reject) => {
        let toDelete = this.keepAliveList.indexOf(targetName)
        if (toDelete !== -1) {
          this.keepAliveList.splice(toDelete, 1)
          resolve(`${targetName}已移除`)
        } else {
          reject(new Error('缓存队列不存在当前准备删除组件'))
        }
      })
    },

    /*
     名称：openTabs
     类型：function
     功能：打开新的标签页面，属于全局方法
     参数：tabName:{permissionCode (跳转标签页的路由),    ROLE_MGR
                   permissionName (),     角色管理
                   params},      这个页面的相关信息   --上面两个参数都是来自这里
    */
    // 打开新页签
    openTabs (tabName) {
      const { permissionCode, permissionName, params = null } = tabName
      // 如果导航路由不存在，打印错误
      if (!permissionCode || permissionCode.length < 4) {
        console.error('导航菜单不存在')
        return
      }

      // 缓存传递过来的参数，类似vue-router的参数，赋值到当前组件名下(参数需为object)
      if (params) {
        this.params[permissionCode] = params
      }

      // 导航路由存在，执行缓存列表推送，然后组件跳转
      this.addKeepList(permissionCode).then(mes => {
        // 判断为新增，添加到缓存队列，否则直接跳转
        if (mes === 'add') {
          this.tabsList.push({ label: permissionName, name: permissionCode })
        }

        this.$nextTick(() => {
          this.tabsActive = permissionCode
          this.setActiveTab()
        })
      })
    },

    // 调用原型上的方法，映射当前标签页到原型属性上
    setActiveTab () {
      this.$setActiveTab(this.tabsActive)
    },
    handleScroll () {
      let main = this.$refs['main-content']
      this.scrollTop = main.wrap.scrollTop
      if (this.scrollTop > 200) {
        this.visiable = true
      } else {
        this.visiable = false
      }
    },
    handleScrollTop () {
      let main = this.$refs['main-content']
      let timer = null
      let _this = this
      cancelAnimationFrame(timer)
      timer = requestAnimationFrame(function fn () {
        if (_this.scrollTop > 0) {
          _this.scrollTop -= 50
          main.wrap.scrollTop = _this.scrollTop
          timer = requestAnimationFrame(fn)
        } else {
          cancelAnimationFrame(timer)
          _this.visiable = false
        }
      })
    }
  },

  created () {
    this.$createTabs()
    // this.$openTabs({ permissionName: '各渠道进度查询', permissionCode: 'ALL_CHANNEL_SEARCH' })
  },
  mounted () {
    this.$nextTick(() => {
      let main = this.$refs['main-content']

      main.wrap.addEventListener('scroll', this.handleScroll, true)
    })

    const { query }= this.$route
    if (query.tabName) {
      let permissionName, permissionCode, params;
      switch (query.tabName) {
        case "QUERY_CASE":
          permissionName = "审批详情";
          permissionCode = "QUERY_CASE";
          params = {
            productType: query.productType,
          };

          this.$store.commit("SYNC_APPROVAL_CASE_ID", {
            caseId: query.caseId,
            flag: "Q"
          });
          break;
      
        default:
          break;
      }
      setTimeout(()=>{
        this.$openTabs({ permissionName, permissionCode, params })
      }, 1000);
    }
  },
  destroyed () {
    let main = this.$refs['main-content']
    main.wrap.removeEventListener('scroll', this.handleScroll)
  },
  watch: {
    contextMenuVisible (value) {
      if (this.contextMenuVisible) {
        document.body.addEventListener('click', this.closeContextMenu)
      } else {
        document.body.removeEventListener('click', this.closeContextMenu)
      }
    }
  }
}
</script>

<style lang="less" scoped>

#content-box {
  position: absolute;
  left: 20px;
  top: 66px;
  right: 0;
  bottom: 0;
  box-sizing: border-box;
  // margin:16px 0 0 16px;
}

#tabs-box {
  box-sizing: border-box;
}

#main-content {
  position: absolute;
  background: #fff;
  width: 100%;
  top: 30px;
  left: 0;
  bottom: 0;
  box-sizing: border-box;
  padding: 20px 20px 0 20px;
  border-left: 1px solid #e4e7ed;
}
.contextmenu {
  width: 100px;
  margin: 0;
  border: 1px solid #ccc;
  background: #fff;
  z-index: 3000;
  position: absolute;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 14px;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.2);
  li {
    margin: 0;
    padding: 7px 16px;
  }
  li:hover {
    background: #f2f2f2;
    cursor: pointer;
  }
}
.back-top-box{
  box-sizing: border-box;
  padding: 10px 15px;
  position: fixed;
  right: 5%;
  bottom: 10%;
  z-index: 999;
  border-radius: 20px;
  cursor: pointer;
  overflow: hidden;
  .mask{
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.6;
    position: absolute;
    z-index: 1;
    left: 0;
    top: 0;
  }
  .content{
    display: flex;
    justify-content: center;
    align-items: center;
    flex-flow: column;
    color: #fff;
    position: relative;
    z-index: 10;
    i{
      font-size: 20px;
      color: #fff;
    }
    p{
      font-size: 14px;
      color: #fff;
    }
  }
}
</style>
